home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
HPAVC
/
HPAVC CD-ROM.iso
/
ABUSESRC.ZIP
/
AbuseSrc
/
macabuse
/
imlib
/
scroller.c
< prev
next >
Wrap
C/C++ Source or Header
|
1997-05-20
|
16KB
|
718 lines
#include "scroller.hpp"
#define HS_ICON_W 10
#define HS_ICON_H 8
unsigned char hs_left_arrow[10*8]={
0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0,
0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1,
1, 1, 1, 1, 2, 0, 1, 1, 2, 2, 2, 2, 2, 2, 2,
0, 0, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
2, 0, 0, 0, 0};
unsigned char hs_right_arrow[10*8]={
0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0,
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1,
1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 1, 1, 0,
0, 0, 0, 0, 0, 2, 1, 1, 0, 0, 0, 0, 0, 0, 2,
1, 1, 0, 0, 0};
unsigned char vs_up_arrow[8*10]={
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 0,
0, 0, 0, 1, 1, 1, 1, 2, 0, 0, 1, 2, 1, 1, 2,
1, 2, 0, 0, 0, 1, 1, 2, 0, 0, 0, 0, 0, 1, 1,
2, 0, 0, 0, 0, 0, 1, 1, 2, 0, 0, 0, 0, 0, 1,
1, 2, 0, 0, 0, 0, 0, 1, 1, 2, 0, 0, 0, 0, 0,
0, 2, 2, 0, 0};
unsigned char vs_down_arrow[8*10]={
0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 1, 1, 2, 0,
0, 0, 0, 0, 1, 1, 2, 0, 0, 0, 0, 0, 1, 1, 2,
0, 0, 0, 0, 0, 1, 1, 2, 0, 0, 0, 0, 0, 1, 1,
2, 0, 0, 0, 1, 2, 1, 1, 2, 1, 2, 0, 0, 1, 1,
1, 1, 2, 0, 0, 0, 0, 1, 1, 2, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0};
void show_icon(image *screen, window_manager *wm, int x, int y, int icw, int ich, unsigned char *buf)
{
short cx1,cy1,cx2,cy2;
screen->get_clip(cx1,cy1,cx2,cy2);
unsigned char remap[3];
remap[0]=wm->medium_color();
remap[1]=wm->bright_color();
remap[2]=wm->dark_color();
for (int yc=ich;yc;yc--,y++)
{
if (y>=cy1 && y<=cy2)
{
unsigned char *sl=screen->scan_line(y)+x;
for (int xc=icw,xo=x;xc;xc--,xo++,sl++,buf++)
{
if (xo>=cx1 && xo<=cx2)
*sl=remap[*buf];
}
}
}
screen->add_dirty(x,y,x+icw-1,y+ich-1);
}
scroller::scroller(int X, int Y, int ID, int L, int H, int Vert, int Total_items, ifield *Next)
{ x=X; y=Y; id=ID; next=Next; l=L; h=H; sx=0; t=Total_items; drag=-1; vert=Vert;
}
void scroller::area(int &x1, int &y1, int &x2, int &y2, window_manager *wm)
{
area_config(wm);
x1=x-1; y1=y-1;
if (vert)
{ x2=x+l+bw(); y2=y+h; }
else
{ x2=x+l; y2=y+h+bh(); }
}
void scroller::dragger_area(int &x1, int &y1, int &x2, int &y2)
{
if (vert)
{ x1=x+l; y1=y+bh(); x2=x+l+bw()-1; y2=y+h-bh()-1; }
else { x1=x+bw(); y1=y+h; x2=x+l-bw(); y2=y+h+bh()-1; }
}
int scroller::bh() { if (vert) return 14; else return 13; }
int scroller::bw() { if (vert) return 12; else return 14; }
unsigned char *scroller::b1()
{
if (vert) return vs_up_arrow;
else return hs_left_arrow;
}
unsigned char *scroller::b2()
{
if (vert) return vs_down_arrow;
else return hs_right_arrow;
}
void scroller::draw_first(image *screen, window_manager *wm)
{
if (sx>=t) sx=t-1;
draw(0,screen,wm);
screen->wiget_bar(b1x(),b1y(),b1x()+bw()-1,b1y()+bh()-1,
wm->bright_color(),wm->medium_color(),wm->dark_color());
screen->wiget_bar(b2x(),b2y(),b2x()+bw()-1,b2y()+bh()-1,
wm->bright_color(),wm->medium_color(),wm->dark_color());
show_icon(screen,wm,b1x()+2,b1y()+2,bw()-4,bh()-4,b1());
show_icon(screen,wm,b2x()+2,b2y()+2,bw()-4,bh()-4,b2());
int x1,y1,x2,y2;
dragger_area(x1,y1,x2,y2);
screen->bar(x1,y1,x2,y2,wm->black());
screen->bar(x1+1,y1+1,x2-1,y2-1,wm->medium_color());
draw_wiget(screen,wm,0);
scroll_event(sx,screen,wm);
}
void scroller::wig_area(int &x1, int &y1, int &x2, int &y2)
{
int sx1,sy1,sx2,sy2;
dragger_area(sx1,sy1,sx2,sy2);
if (vert)
{
x1=x+l+1;
if (t<2)
y1=y+bh()+1;
else
y1=y+bh()+1+sx*(sy2-sy1+1-bh())/(t-1);
} else
{
if (t<2) x1=x+bw()+1;
else x1=x+bw()+1+sx*(sx2-sx1+1-bw())/(t-1);
y1=y+h+1;
}
x2=x1+bw()-3;
y2=y1+bh()-3;
}
void scroller::draw_wiget(image *screen, window_manager *wm, int erase)
{
int x1,y1,x2,y2;
wig_area(x1,y1,x2,y2);
if (erase)
screen->bar(x1,y1,x2,y2,wm->medium_color());
else
screen->wiget_bar(x1,y1,x2,y2,
wm->bright_color(),wm->medium_color(),wm->dark_color());
}
void scroller::draw(int active, image *screen, window_manager *wm)
{
int x1,y1,x2,y2;
area(x1,y1,x2,y2,wm);
screen->rectangle(x1,y1,x2,y2,active ? wm->bright_color() : wm->dark_color());
}
void scroller::handle_event(event &ev, image *screen, window_manager *wm, input_manager *inm)
{
int mx=ev.mouse_move.x,my=ev.mouse_move.y;
switch (ev.type)
{
case EV_MOUSE_BUTTON :
{
if (ev.mouse_button && drag==-1)
{
if (mx>=b1x() && mx<b1x()+bw() && my>=b1y()-2 && my<b1y()+bh())
{
if (sx>0)
{
draw_wiget(screen,wm,1);
sx--;
draw_wiget(screen,wm,0);
scroll_event(sx,screen,wm);
}
} else if (mx>=b2x() && mx<b2x()+bw() && my>=b2y() && my<=b2y()+bh())
{
if (sx<t-1)
{
draw_wiget(screen,wm,1);
sx++;
draw_wiget(screen,wm,0);
scroll_event(sx,screen,wm);
}
}
else
{
int dx1,dy1,dx2,dy2;
dragger_area(dx1,dy1,dx2,dy2);
if (mx>=dx1 && mx<=dx2 && my>=dy1 && my<=dy2)
{
int x1,y1,x2,y2;
wig_area(x1,y1,x2,y2);
if (mx>=x1 && mx<=x2 && my>=y1 && my<=y2)
{
drag=sx;
inm->grab_focus(this);
}
else if (t>1)
{
int nx=mouse_to_drag(mx,my);
if (nx!=sx && nx>=0 && nx<t)
{
draw_wiget(screen,wm,1);
sx=nx;
draw_wiget(screen,wm,0);
scroll_event(sx,screen,wm);
}
}
} else handle_inside_event(ev,screen,wm,inm);
}
} else if (!ev.mouse_button && drag!=-1)
{
inm->release_focus();
drag=-1;
}
} break;
case EV_MOUSE_MOVE :
{
if (drag!=-1)
{
int nx=mouse_to_drag(mx,my);
if (nx<0) nx=0; else if (nx>=t) nx=t-1;
if (nx!=sx)
{
draw_wiget(screen,wm,1);
sx=nx;
draw_wiget(screen,wm,0);
scroll_event(sx,screen,wm);
}
} else if ( activate_on_mouse_move())
{
int x1,y1,x2,y2;
wig_area(x1,y1,x2,y2);
if (mx>=x && mx<=x+l-1 && my>=y && my<=y+h-1)
handle_inside_event(ev,screen,wm,inm);
}
} break;
case EV_KEY :
{
switch (ev.key)
{
case JK_LEFT :
{ handle_left(screen,wm,inm); } break;
case JK_RIGHT :
{ handle_right(screen,wm,inm); } break;
case JK_UP :
{ handle_up(screen,wm,inm); } break;
case JK_DOWN :
{ handle_down(screen,wm,inm); } break;
default :
handle_inside_event(ev,screen,wm,inm);
}
} break;
}
}
void scroller::handle_right(image *screen, window_manager *wm, input_manager *inm)
{
if (!vert && sx<t-1)
{
draw_wiget(screen,wm,1);
sx++;
draw_wiget(screen,wm,0);
scroll_event(sx,screen,wm);
}
}
void scroller::handle_left(image *screen, window_manager *wm, input_manager *inm)
{
if (!vert && sx>1)
{
draw_wiget(screen,wm,1);
sx--;
draw_wiget(screen,wm,0);
scroll_event(sx,screen,wm);
}
}
void scroller::handle_up(image *screen, window_manager *wm, input_manager *inm)
{
if (vert && sx>1)
{
draw_wiget(screen,wm,1);
sx--;
draw_wiget(screen,wm,0);
scroll_event(sx,screen,wm);
}
}
void scroller::handle_down(image *screen, window_manager *wm, input_manager *inm)
{
if (vert && sx<t-1)
{
draw_wiget(screen,wm,1);
sx++;
draw_wiget(screen,wm,0);
scroll_event(sx,screen,wm);
}
}
void scroller::set_x (int x, image *screen, window_manager *wm)
{
if (x<0) x=0;
if (x>=t) x=t-1;
if (x!=sx)
{
draw_wiget(screen,wm,1);
sx=x;
draw_wiget(screen,wm,0);
scroll_event(sx,screen,wm);
}
}
int scroller::mouse_to_drag(int mx,int my)
{
int x1,y1,x2,y2;
dragger_area(x1,y1,x2,y2);
if (vert)
{
int h=(y2-y1+1-bh());
if (h)
return (my-y-bh()-bh()/2)*(t-1)/h;
else return 0;
}
else
{
int w=(x2-x1+1-bw());
if (w)
return (mx-x-bw()-bw()/2)*(t-1)/w;
else return 0;
}
}
void scroller::scroll_event(int newx, image *screen, window_manager *wm)
{
screen->bar(x,y,x+l-1,y+h-1,wm->black());
int xa,ya,xo,yo;
if (vert) { xa=0; ya=30; yo=x+5; yo=y+5; } else { xa=30; ya=0; xo=x+5; yo=y+5; }
for (int i=newx,c=0;c<30 && i<100;i++,c++)
{
char st[10];
sprintf(st,"%d",i);
wm->font()->put_string(screen,xo,yo,st,wm->bright_color());
xo+=xa; yo+=ya;
}
}
void pick_list::area_config(window_manager *wm)
{
l=wid*wm->font()->width();
h=th*(wm->font()->height()+1);
}
int lis_sort(void const *a, void const *b)
{
pick_list_item *a1=(pick_list_item *)a;
pick_list_item *a2=(pick_list_item *)b;
return strcmp(a1->name,a2->name);
}
pick_list::pick_list(int X, int Y, int ID, int height,
char **List, int num_entries, int start_yoffset, ifield *Next, image *texture)
: scroller(X,Y,ID,2,2,1,0,Next)
{
th=height;
tex=texture;
t=num_entries;
wid=0;
key_hist_total=0;
lis=(pick_list_item *)jmalloc(sizeof(pick_list_item)*num_entries,"pick list");
int i=0;
for (;i<num_entries;i++)
{
lis[i].name=List[i];
lis[i].number=i;
}
qsort((void *)lis,num_entries,sizeof(pick_list_item),lis_sort);
for (i=0;i<t;i++)
if (strlen(List[i])>wid)
wid=strlen(List[i]);
cur_sel=sx=start_yoffset;
}
void pick_list::handle_inside_event(event &ev, image *screen, window_manager *wm, input_manager *inm)
{
if (ev.type==EV_MOUSE_MOVE && activate_on_mouse_move())
{
int sel=last_sel+(ev.mouse_move.y-y)/(wm->font()->height()+1);
if (sel!=cur_sel && sel<t && sel>=0)
{
cur_sel=sel;
scroll_event(last_sel,screen,wm);
}
}
else if (ev.type==EV_MOUSE_BUTTON)
{
int sel=last_sel+(ev.mouse_move.y-y)/(wm->font()->height()+1);
if (sel<t && sel>=0)
{
if (sel==cur_sel)
wm->push_event(new event(id,(char *)this));
else
{
cur_sel=sel;
scroll_event(last_sel,screen,wm);
}
}
} else if (ev.type==EV_KEY && ev.key==JK_ENTER)
wm->push_event(new event(id,(char *)this));
else if (ev.type==EV_KEY)
{
int found=-1;
if (key_hist_total<20)
key_hist[key_hist_total++]=ev.key;
for (int i=0;i<t && found==-1;i++)
{
if (strlen(lis[i].name)>=key_hist_total && memcmp(lis[i].name,key_hist,key_hist_total)==0)
found=i;
}
if (found!=-1)
{
sx=found;
cur_sel=found;
scroll_event(sx,screen,wm);
} else key_hist_total=0;
}
}
void pick_list::handle_up(image *screen, window_manager *wm, input_manager *inm)
{
if (cur_sel>0)
cur_sel--;
else return ;
if (cur_sel<sx)
{
draw_wiget(screen,wm,1);
sx=cur_sel;
draw_wiget(screen,wm,0);
}
scroll_event(sx,screen,wm);
}
void pick_list::handle_down(image *screen, window_manager *wm, input_manager *inm)
{
if (cur_sel<t-1)
cur_sel++;
else return ;
if (cur_sel>sx+th-1)
{
draw_wiget(screen,wm,1);
sx=cur_sel-th+1;
draw_wiget(screen,wm,0);
}
scroll_event(sx,screen,wm);
}
void pick_list::scroll_event(int newx, image *screen, window_manager *wm)
{
last_sel=newx;
if (tex)
{
short cx1,cy1,cx2,cy2;
screen->get_clip(cx1,cy1,cx2,cy2);
screen->set_clip(x,y,x+l-1,y+h-1);
int tw=(l+tex->width()-1)/tex->width();
int th=(h+tex->height()-1)/tex->height();
int dy=y,dx;
for (int j=0;j<th;j++,dy+=tex->height())
for (int i=0,dx=x;i<tw;i++,dx+=tex->width())
tex->put_image(screen,dx,dy);
screen->set_clip(cx1,cy1,cx2,cy2);
} else screen->bar(x,y,x+l-1,y+h-1,wm->black());
int dy=y;
for (int i=0;i<th;i++,dy+=wm->font()->height()+1)
{
if (i+newx==cur_sel)
screen->bar(x,dy,x+wid*wm->font()->width()-1,dy+wm->font()->height(),wm->dark_color());
if (i+newx<t)
wm->font()->put_string(screen,x,dy,lis[i+newx].name,wm->bright_color());
}
}
spicker::spicker(int X, int Y, int ID, int Rows, int Cols, int Vert, int MultiSelect,
ifield *Next)
: scroller(X,Y,ID,2,2,Vert,0,Next)
{
l=-1;
last_click=-1;
r=Rows;
c=Cols;
m=MultiSelect;
select=NULL;
}
void spicker::set_select(int x, int on)
{
if (m)
{
if (on)
select[x/8]|=1<<(x&7);
else
select[x/8]&=(0xff-(1<<(x&7)));
} else cur_sel=x;
}
int spicker::get_select(int x)
{
if (m)
return select[x/8]&(1<<(x&7));
else return (x==cur_sel);
}
int spicker::first_selected()
{
if (m)
{
for (int i=0;i<t;i++)
if (get_select(i)) return i;
return -1;
} else return cur_sel;
}
void spicker::reconfigure()
{
if (select)
jfree(select);
select=NULL;
t=total();
if (sx>t)
sx=t-1;
if (m)
{
select=(uchar *)jmalloc((t+7)/8,"selection bit array");
memset(select,0,(t+7)/8);
} else cur_sel=0;
}
void spicker::draw_background(window_manager *wm, image *screen)
{
screen->bar(x,y,x+l-1,y+h-1,wm->dark_color());
}
void spicker::area_config(window_manager *wm)
{
if (vert)
l=item_width(wm)+4;
else
l=item_width(wm)*c+4;
if (vert)
h=item_height(wm)*r+4;
else
h=item_height(wm)+4;
}
void spicker::set_x(int x, image *screen, window_manager *wm)
{
cur_sel=x;
sx=x;
scroll_event(x,screen,wm);
}
void spicker::scroll_event(int newx, image *screen, window_manager *wm)
{
last_sel=newx;
int xa,ya,xo,yo;
xo=x+2;
yo=y+2;
if (vert) { xa=0; ya=item_height(wm); }
else { xa=item_width(wm); ya=0; }
draw_background(wm,screen);
for (int i=newx;i<newx+vis();i++)
{
if (i>=0 && i<t)
{
if (m)
draw_item(wm,screen,xo,yo,i,get_select(i));
else
draw_item(wm,screen,xo,yo,i,i==cur_sel);
}
xo+=xa; yo+=ya;
}
}
void spicker::handle_inside_event(event &ev, image *screen, window_manager *wm, input_manager *inm)
{
switch (ev.type)
{
case EV_MOUSE_MOVE :
{
if (activate_on_mouse_move())
{
int me;
if (vert)
me=last_sel+(ev.mouse_move.y-y)/item_height(wm);
else
me=last_sel+(ev.mouse_move.x-x)/item_width(wm);
if (me<t && me>=0)
{
if (cur_sel!=me)
{
cur_sel=me;
scroll_event(last_sel,screen,wm);
note_new_current(wm,screen,inm,me);
}
}
}
} break;
case EV_MOUSE_BUTTON :
{
int me;
if (vert)
me=last_sel+(ev.mouse_move.y-y)/item_height(wm);
else
me=last_sel+(ev.mouse_move.x-x)/item_width(wm);
if (me<t && me>=0)
{
if (m)
{
if (ev.mouse_button)
{
if (ok_to_select(me))
{
set_select(me,!get_select(me));
scroll_event(last_sel,screen,wm);
inm->grab_focus(this);
}
} else last_click=-1;
} else if (ok_to_select(me))
{
if (cur_sel==me)
note_selection(wm,screen,inm,me);
else
{
cur_sel=me;
scroll_event(last_sel,screen,wm);
note_new_current(wm,screen,inm,me);
}
}
}
} break;
}
}
void spicker::handle_up(image *screen, window_manager *wm, input_manager *inm)
{
if (vert && cur_sel>0)
{
cur_sel--;
if (cur_sel<sx)
{
draw_wiget(screen,wm,1);
last_sel=sx=cur_sel;
draw_wiget(screen,wm,0);
}
scroll_event(last_sel,screen,wm);
note_new_current(wm,screen,inm,cur_sel);
}
}
void spicker::handle_down(image *screen, window_manager *wm, input_manager *inm)
{
if (vert && cur_sel<t-1)
cur_sel++;
else return ;
if (cur_sel>sx+r-1)
{
draw_wiget(screen,wm,1);
last_sel=sx=cur_sel-r+1;
draw_wiget(screen,wm,0);
}
scroll_event(sx,screen,wm);
note_new_current(wm,screen,inm,cur_sel);
}
void spicker::handle_left(image *screen, window_manager *wm, input_manager *inm)
{
}
void spicker::handle_right(image *screen, window_manager *wm, input_manager *inm)
{
}